package com.eryos.android.cigarettecounter;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources.NotFoundException;
import android.database.SQLException;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;

import com.eryos.android.cigarettecounter.database.CigaretteDatabase;
import com.eryos.android.cigarettecounter.io.Preferences;


/**
 * Project :  CigaretteCounter
 * Author :   Olivier Combe 
 * URL :      http://eryos.fr/CigaretteCounter/
 *
 * Copyright (C) 2011 - Olivier Combe 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 *
 */

public class CigaretteWidget extends AppWidgetProvider {

	/** *************** Static Variables *************** **/
	private static final String ACTION_WIDGET_CONTROL 	= "com.eryos.android.cigarettecounter.WIDGET_CONTROL";
	private static final String ACTION_WIDGET_UPDATE 	= "com.eryos.android.cigarettecounter.WIDGET_UPDATE";

	private final static String LOG_TAG = "CigaretteWidget";
	private static int[] widgetIDs;

	/** *************** Instance Variables *************** **/
	private CigaretteDatabase db;
	private int today = 0;	
	
	/** *************** Overriden Methods *************** **/
	
	/**
	 * Method called when the Widget is enabled
	 * @param context
	 */
	@Override
	public void onEnabled(Context context){
		Log.i(LOG_TAG, "onEnabled");
		db = CigaretteDatabase.getInstance(context);
		db.open();
		if ( db != null )
			Log.d(LOG_TAG, "init DB OK");
	}
	
	/**
	 * Method called when the Widget is disabled
	 * @param context
	 */
	@Override
	public void onDisabled(Context context){
		Log.i(LOG_TAG, "onDisabled");
		if ( db != null ) 
			db.close();
	}

	/**
	 * Method called when and APPWIDGET_UPDATE action is raised
	 * @param context
	 * @param appWidgetManager
	 * @param appWidgetIds : list of Widget's IDs
	 */
	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
		Log.i(LOG_TAG, "onUpdate()");

		if ( db == null )
			db = CigaretteDatabase.getInstance(context);

		today = db.getDailyCount();

		widgetIDs = new int[appWidgetIds.length];
		for ( int i = 0 ; i < appWidgetIds.length ; i++ ) {
			widgetIDs[i] = appWidgetIds[i];
			Log.d(LOG_TAG, "onUpdate(): "+appWidgetIds[i]);

			RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.widget);

			/* modify remoteView based on current state */
			updateDisplay(context, remoteView, appWidgetIds[i]);
		}
	}

	/**
	 * Method called when an action is raised ( called before onUpdate, onEnabled, onDisabled, etc.)
	 * @param context
	 * @param intent
	 */
	@Override
	public void onReceive(Context context, Intent intent) {
		try {
			final String action = intent.getAction();
			Log.i(LOG_TAG, "onReceive Action : " + action);

//			if ( ACTION_WIDGET_UPDATE.equals(action) || ACTION_WIDGET_CONTROL.equals(action) ){
				// pass this on to the action handler where we'll figure out what to do and update the widget
				/*final int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
				final RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.widget);

				if ( db == null )
					db = CigaretteDatabase.getInstance(context);
			*/
				if (ACTION_WIDGET_UPDATE.equals(action)) {
					if ( db == null )
						db = CigaretteDatabase.getInstance(context);

					today = db.getDailyCount();
					Log.d(LOG_TAG, "Today : "+today);
	
					// pass this on to the action handler where we'll figure out what to do and update the widget
					final int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
					final RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.widget);
	
					if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
						Log.d(LOG_TAG, "onReceive : update Current Widget");
	
						updateDisplay(context, remoteView,  appWidgetId);
					}else {
						Log.d(LOG_TAG, "onReceive : updata All Widgets");
	
						for ( int widgetId : widgetIDs )
							updateDisplay(context, remoteView,  widgetId);						
					}
					
				}else if (ACTION_WIDGET_CONTROL.equals(action)) {
					// pass this on to the action handler where we'll figure out what to do and update the widget
					final int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
					final RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.widget);
	
					if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
						Preferences pref = new Preferences(context.getSharedPreferences(CigaretteCounter.PREFS_NAME, 0));
						pref.readParamFromFile();
						float cigarettePrice = pref.getCigarettePrice();
	
						if ( db == null )
							db = CigaretteDatabase.getInstance(context);
	
						db.insertCurrentTimestamp("Widget", cigarettePrice);
						today = db.getDailyCount();
	
						Toast.makeText(context, R.string.home_insert_OK, Toast.LENGTH_SHORT).show();
	
						updateDisplay(context, remoteView,  appWidgetId);
					}else{
						Log.w(LOG_TAG, "Invalid AppWidget ID");
					}
	
				} else {
					super.onReceive(context, intent);
				}
//			}
		} catch (NotFoundException e) {
			Log.e(LOG_TAG, "onReceive(NotFoundExeption)", e);
		} catch (SQLException e) {
			Log.e(LOG_TAG, "onReceive(SQLException)", e);
		} catch (Throwable e) {
			Log.e(LOG_TAG, "onReceive(Throwable)", e);
		}
	}

	/**
	 * Method used to refresh the Widget's UI
	 * @param context
	 * @param remoteView
	 * @param appWidgetId
	 */
	public void updateDisplay(Context context, RemoteViews remoteView,  int appWidgetId) {
		Log.i(LOG_TAG, "updateDisplayState");

		try {
			remoteView.setTextViewText(R.id.TextView01, "Today :");
			remoteView.setTextViewText(R.id.TextView02, today+"");
			remoteView.setOnClickPendingIntent(R.id.Button01, makeControlPendingIntent(context, "active", appWidgetId));
		} catch (Exception e) {
			Log.e(LOG_TAG, "updateDisplay", e);
		}

		/* Call the AppWidgetManager to update the widget's UI */
		AppWidgetManager.getInstance(context).updateAppWidget(appWidgetId, remoteView);
	}

	/**
	 * Method used to raise an action when the user click on the widget's button
	 * @param context
	 * @param command
	 * @param appWidgetId
	 * @return
	 */
	private PendingIntent makeControlPendingIntent(Context context, String command, int appWidgetId) {
		Log.i(LOG_TAG, "makeControlPendingIntent : "+command);

		Intent active;
		active = new Intent();
		active.setAction(ACTION_WIDGET_CONTROL);
		active.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);

		return(PendingIntent.getBroadcast(context, 0, active, PendingIntent.FLAG_UPDATE_CURRENT/*.FLAG_ONE_SHOT*/));
	}

	/**
	 * Method used to refresh all Widgets
	 * @param context : current context
	 */
	public static void updateWidgets(Context context){
		Log.i(LOG_TAG, "updateWidgets()");
		try {
			if (widgetIDs != null ){
	    		for ( int widgetId : widgetIDs ){
		    		Intent active = new Intent();
					active.setAction(ACTION_WIDGET_UPDATE);
					active.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
					PendingIntent pi = (PendingIntent.getBroadcast(context, 0, active, PendingIntent.FLAG_UPDATE_CURRENT/*.FLAG_ONE_SHOT*/));					
					pi.send();
				}
			}else{
	    		Intent active = new Intent();
				active.setAction(ACTION_WIDGET_UPDATE);
				active.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0);
				PendingIntent pi = (PendingIntent.getBroadcast(context, 0, active, PendingIntent.FLAG_UPDATE_CURRENT/*.FLAG_ONE_SHOT*/));				
				pi.send();
			}
		} catch (Exception e) {			
			Log.e(LOG_TAG, "updateWidgets Intent", e);
		}
	}
}

